//
//  XMRefreshControl.swift
//  微博
//
//  Created by xm on 2018/4/1.
//  Copyright © 2018年 xm. All rights reserved.
//

import UIKit

//刷新状态切换临界点高度
private let refreshStateHeight: CGFloat = 60

/// 刷新状态枚举类型
///
/// - Normal: 普通状态什么也不做
/// - Pulling: 超过临界点，如果放手 开始刷新
/// - Refreshing: 用户超过临界点，并且放手了正在刷新状态
enum RefreshState {
    case Normal
    case Pulling
    case Refreshing
}

/// 自定义下啦刷新试图
// 所有的第三方下啦刷新控件 都是这个原理
// 利用KVO方法监听父试图的 contentOffset变化实现刷新控件随着下啦改变大小和状态
class XMRefreshControl: UIControl {
    //刷新控件的父视图，只用继承了UIScrollView的控件都可以用
    var scrollView: UIScrollView?
    var refreshView: RefreshView?//刷新视图
    
    /// 构造函数
    init() {
        super.init(frame: CGRect())
        
        setupUI()
    }
    //xlib构造函数也可以用
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        setupUI()
    }
    
    
    
    /// 将要添加到父视图回调方法
    ///
    /// - Parameter newSuperview: 父试图
    override func willMove(toSuperview newSuperview: UIView?) {
        // 判断newSuperview是否为nil 而且是否是一个滚动视图
        guard let s = newSuperview as? UIScrollView else {
            return
        }
        // 记录
        scrollView = s
        // 注册观察者
        s.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.new, context: nil)
    }
    
    override func removeFromSuperview() {
        super.removeFromSuperview()
        //取消注册观察者
        removeObserver(self, forKeyPath: "contentOffset")
    }
    
    /// 观察者模式，统一回调方法
    ///
    /// - Parameters:
    ///   - keyPath: <#keyPath description#>
    ///   - object: <#object description#>
    ///   - change: <#change description#>
    ///   - context: <#context description#>
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        guard let sv = scrollView else{
            return
        }
        
        let height = -(sv.contentInset.top + sv.contentOffset.y)
        
        if height < 0 {
            return
        }
        
        //改变高度，下啦刷新试图也变大
        self.frame = CGRect(x: 0,
                            y: -height,
                            width: sv.bounds.width,
                            height: height)
        
        if sv.isDragging {//用户拖拽中没有放手
            if height > refreshStateHeight && (refreshView?.refreshState == RefreshState.Normal) {
                print("超过临近点 放手就刷新")
                refreshView?.refreshState = RefreshState.Pulling
            }else if height < refreshStateHeight && (refreshView?.refreshState == RefreshState.Pulling){
                print("没有拽到位置。。")
                refreshView?.refreshState = RefreshState.Normal
            }
        }else{//用户放手了
            //用户放手了判断是否过了临界点且
            if refreshView?.refreshState == RefreshState.Pulling{
                refreshView?.refreshState = RefreshState.Refreshing
            }
            
        }
    }
    
    
    func endRefreshing(){
        
        
    }
    
    func beginRefreshing(){
        
    }

}

extension XMRefreshControl {
    
    func setupUI() {
        backgroundColor = superview?.backgroundColor
        refreshView = RefreshView()//刷新视图
        addSubview(refreshView!)
        refreshView?.translatesAutoresizingMaskIntoConstraints=false;//取消
        //使用苹果原生方法添加自动布局
        addConstraints([NSLayoutConstraint(item: refreshView!, attribute: .height,
                                           relatedBy: .equal, toItem: self,
                                           attribute: .height, multiplier: 1.0, constant: 0),
                        NSLayoutConstraint(item: refreshView!, attribute: .width,
                                           relatedBy: .equal, toItem: self,
                                           attribute: .width, multiplier: 1.0, constant: 0),
                        NSLayoutConstraint(item: refreshView!, attribute: .bottom,
                                           relatedBy: .equal, toItem: self,
                                           attribute: .bottom, multiplier: 1.0, constant: 0)])
       
    }
    
}
